﻿/*!	@file
	共通設定ダイアログボックス、「プラグイン」ページ

	@author syat
*/
/*
	Copyright (C) 2009, syat
	Copyright (C) 2018-2022, Sakura Editor Organization

	SPDX-License-Identifier: Zlib
*/

#include "StdAfx.h"
#include <shellapi.h>
#include "prop/CPropCommon.h"
#include "CEditApp.h"
#include "plugin/CJackManager.h"
#include "uiparts/CMenuDrawer.h"
#include "util/shell.h"
#include "dlg/CDlgOpenFile.h"
#include "dlg/CDlgPluginOption.h"	// 2010/3/22 Uchi
#include "io/CTextStream.h"
#include "io/CZipFile.h"
#include "CSelectLang.h"
#include "util/shell.h"
#include "sakura_rc.h"
#include "sakura.hh"
#include "config/app_constants.h"
#include "String_define.h"

static void LoadPluginTemp(CommonSetting& common, CMenuDrawer& cMenuDrawer);

//! Popup Help用ID
static const DWORD p_helpids[] = {	//11700
	IDC_CHECK_PluginEnable,	HIDC_CHECK_PluginEnable,	//プラグインを有効にする
	IDC_PLUGINLIST,			HIDC_PLUGINLIST,			//プラグインリスト
	IDC_PLUGIN_INST_ZIP,	HIDC_PLUGIN_INST_ZIP,		//Zipプラグインを追加	// 2011/11/2 Uchi
	IDC_PLUGIN_SearchNew,	HIDC_PLUGIN_SearchNew,		//新規プラグインを追加
	IDC_PLUGIN_OpenFolder,	HIDC_PLUGIN_OpenFolder,		//フォルダーを開く
	IDC_PLUGIN_Remove,		HIDC_PLUGIN_Remove,			//プラグインを削除
	IDC_PLUGIN_OPTION,		HIDC_PLUGIN_OPTION,			//プラグイン設定	// 2010/3/22 Uchi
	IDC_PLUGIN_README,		HIDC_PLUGIN_README,			//ReadMe表示		// 2011/11/2 Uchi
	IDC_PLUGIN_URL,			HIDC_PLUGIN_URL,			//配布先			// 2015/01/02 syat
	//	IDC_STATIC,			-1,
	0, 0
};

/*!
	@param hwndDlg ダイアログボックスのWindow Handle
	@param uMsg メッセージ
	@param wParam パラメータ1
	@param lParam パラメータ2
*/
INT_PTR CALLBACK CPropPlugin::DlgProc_page(
	HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	return DlgProc( reinterpret_cast<pDispatchPage>(&CPropPlugin::DispatchEvent), hwndDlg, uMsg, wParam, lParam );
}

/*! Pluginページのメッセージ処理
	@param hwndDlg ダイアログボックスのWindow Handlw
	@param uMsg メッセージ
	@param wParam パラメータ1
	@param lParam パラメータ2
*/
INT_PTR CPropPlugin::DispatchEvent( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	NMHDR*		pNMHDR;
	int			idCtrl;

	WORD		wNotifyCode;
	WORD		wID;

	switch( uMsg ){

	case WM_INITDIALOG:
		/* ダイアログデータの設定 Plugin */
		InitDialog( hwndDlg );
		SetData( hwndDlg );
		// Modified by KEITA for WIN64 2003.9.6
		::SetWindowLongPtr( hwndDlg, DWLP_USER, lParam );

		return TRUE;
	case WM_NOTIFY:
		idCtrl = (int)wParam;
		pNMHDR = (NMHDR*)lParam;
		switch( idCtrl ){
		case IDC_PLUGINLIST:
			switch( pNMHDR->code ){
			case LVN_ITEMCHANGED:
				{
					HWND hListView = ::GetDlgItem( hwndDlg, IDC_PLUGINLIST );
					int sel = ListView_GetNextItem( hListView, -1, LVNI_SELECTED );
					if( sel >= 0 ){
						CPlugin* plugin = CPluginManager::getInstance()->GetPlugin(sel);
						if( plugin != nullptr ){
							::SetWindowText( ::GetDlgItem( hwndDlg, IDC_LABEL_PLUGIN_Description ), plugin->m_sDescription.c_str() );
							::SetWindowText( ::GetDlgItem( hwndDlg, IDC_LABEL_PLUGIN_Author ), plugin->m_sAuthor.c_str() );
							::SetWindowText( ::GetDlgItem( hwndDlg, IDC_LABEL_PLUGIN_Version ), plugin->m_sVersion.c_str() );
						}else{
							::SetWindowText( ::GetDlgItem( hwndDlg, IDC_LABEL_PLUGIN_Description ), L"" );
							::SetWindowText( ::GetDlgItem( hwndDlg, IDC_LABEL_PLUGIN_Author ), L"" );
							::SetWindowText( ::GetDlgItem( hwndDlg, IDC_LABEL_PLUGIN_Version ), L"" );
						}
						// 2010.08.21 明らかに使えないときはDisableにする
						EPluginState state = m_Common.m_sPlugin.m_PluginTable[sel].m_state;
						BOOL bEdit = (state != PLS_DELETED && state != PLS_NONE);
						::EnableWindow( ::GetDlgItem( hwndDlg, IDC_PLUGIN_Remove ), bEdit );
						::EnableWindow( ::GetDlgItem( hwndDlg, IDC_PLUGIN_OPTION ), state == PLS_LOADED && plugin && plugin->m_options.size() > 0 );
						::EnableWindow( ::GetDlgItem( hwndDlg, IDC_PLUGIN_README ), 
							(state == PLS_INSTALLED || state == PLS_UPDATED || state == PLS_LOADED || state == PLS_DELETED)
							&& !GetReadMeFile(m_Common.m_sPlugin.m_PluginTable[sel].m_szName).empty());
						::EnableWindow(::GetDlgItem(hwndDlg, IDC_PLUGIN_URL), state == PLS_LOADED && plugin && plugin->m_sUrl.size() > 0);
					}
				}
				break;
			case NM_DBLCLK:
				// リストビューへのダブルクリックで「プラグイン設定」を呼び出す
				if (::IsWindowEnabled(::GetDlgItem( hwndDlg, IDC_PLUGIN_OPTION )))
				{
					DispatchEvent( hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_PLUGIN_OPTION, BN_CLICKED), (LPARAM)::GetDlgItem( hwndDlg, IDC_PLUGIN_OPTION ) );
				}
				break;
			}
			break;
		default:
			switch( pNMHDR->code ){
			case PSN_HELP:
				OnHelp( hwndDlg, IDD_PROP_PLUGIN );
				return TRUE;
			case PSN_KILLACTIVE:
				/* ダイアログデータの取得 Plugin */
				GetData( hwndDlg );
				return TRUE;
			case PSN_SETACTIVE:
				m_nPageNum = ID_PROPCOM_PAGENUM_PLUGIN;
				return TRUE;
			}
			break;
		}
		break;

	case WM_COMMAND:
		wNotifyCode = HIWORD(wParam);	/* 通知コード */
		wID = LOWORD(wParam);			/* 項目ID､ コントロールID､ またはアクセラレータID */

		switch( wNotifyCode ){
		/* ボタン／チェックボックスがクリックされた */
		case BN_CLICKED:
			switch( wID ){
			case IDC_PLUGIN_SearchNew:		// 新規プラグインを追加
				GetData( hwndDlg );
				CPluginManager::getInstance()->SearchNewPlugin( m_Common, hwndDlg );
				if( m_bTrayProc ){
					LoadPluginTemp(m_Common, *m_pcMenuDrawer);
				}
				SetData_LIST( hwndDlg );	//リストの再構築
				break;
			case IDC_PLUGIN_INST_ZIP:		// ZIPプラグインを追加
				{
					static std::wstring	sTrgDir;
					CDlgOpenFile	cDlgOpenFile;
					WCHAR			szPath[_MAX_PATH + 1];
					wcscpy( szPath, (sTrgDir.empty() ? CPluginManager::getInstance()->GetBaseDir().c_str() : sTrgDir.c_str()));
					// ファイルオープンダイアログの初期化
					cDlgOpenFile.Create(
						G_AppInstance(),
						hwndDlg,
						L"*.zip",
						szPath
					);
					if( cDlgOpenFile.DoModal_GetOpenFileName( szPath ) ){
						GetData( hwndDlg );
						CPluginManager::getInstance()->InstZipPlugin( m_Common, hwndDlg, szPath );
						if( m_bTrayProc ){
							LoadPluginTemp(m_Common, *m_pcMenuDrawer);
						}
						SetData_LIST( hwndDlg );	//リストの再構築
					}
					// フォルダーを記憶
					WCHAR	szFolder[_MAX_PATH + 1];
					WCHAR	szFname[_MAX_PATH + 1];
					SplitPath_FolderAndFile(szPath, szFolder, szFname);
					sTrgDir = szFolder;
				}
				break;
			case IDC_CHECK_PluginEnable:	// プラグインを有効にする
				EnablePluginPropInput( hwndDlg );
				break;
			case IDC_PLUGIN_Remove:			// プラグインを削除
				{
					HWND hListView = ::GetDlgItem( hwndDlg, IDC_PLUGINLIST );
					int sel = ListView_GetNextItem( hListView, -1, LVNI_SELECTED );
					if( sel >= 0 ){
						
						if( MYMESSAGEBOX( hwndDlg, MB_YESNO, GSTR_APPNAME, LS(STR_PROPCOMPLG_DELETE), m_Common.m_sPlugin.m_PluginTable[sel].m_szName ) == IDYES ){
							CPluginManager::getInstance()->UninstallPlugin( m_Common, sel );
							SetData_LIST( hwndDlg );
						}
					}
				}
				break;
			case IDC_PLUGIN_OPTION:		// プラグイン設定	// 2010/3/22 Uchi
				{
					HWND hListView = ::GetDlgItem( hwndDlg, IDC_PLUGINLIST );
					int sel = ListView_GetNextItem( hListView, -1, LVNI_SELECTED );
					if( sel >= 0 && m_Common.m_sPlugin.m_PluginTable[sel].m_state == PLS_LOADED ){
						// 2010.08.21 プラグイン名(フォルダー名)の同一性の確認
						CPlugin* plugin = CPluginManager::getInstance()->GetPlugin(sel);
						std::wstring sDirName = plugin->GetFolderName();
						if( plugin && 0 == wmemicmp(sDirName.c_str(), m_Common.m_sPlugin.m_PluginTable[sel].m_szName ) ){
							CDlgPluginOption cDlgPluginOption;
							cDlgPluginOption.DoModal( ::GetModuleHandle(nullptr), hwndDlg, this, sel );
						}else{
							WarningMessage( hwndDlg, LS(STR_PROPCOMPLG_ERR1) );
						}
					}
				}
				break;
			case IDC_PLUGIN_OpenFolder:			// フォルダーを開く
				{
					std::wstring sBaseDir = CPluginManager::getInstance()->GetBaseDir() + L".";
					if( ! IsDirectory(sBaseDir.c_str()) ){
						if( ::CreateDirectory(sBaseDir.c_str(), nullptr) == 0 ){
							break;
						}
					}
					::ShellExecute( nullptr, L"open", sBaseDir.c_str(), nullptr, nullptr, SW_SHOW );
				}
				break;
			case IDC_PLUGIN_README:		// ReadMe表示	// 2011/11/2 Uchi
				{
					HWND hListView = ::GetDlgItem( hwndDlg, IDC_PLUGINLIST );
					int sel = ListView_GetNextItem( hListView, -1, LVNI_SELECTED );
					std::wstring sName = m_Common.m_sPlugin.m_PluginTable[sel].m_szName;	// 個別フォルダー名
					std::wstring sReadMeName = GetReadMeFile(sName);
					if (!sReadMeName.empty()) {
						if (!BrowseReadMe(sReadMeName)) {
							WarningMessage( hwndDlg, LS(STR_PROPCOMPLG_ERR2) );
						}
					}else{
						WarningMessage( hwndDlg, LS(STR_PROPCOMPLG_ERR3) );
					}
				}
				break;
			case IDC_PLUGIN_URL:
				{
					HWND hListView = ::GetDlgItem(hwndDlg, IDC_PLUGINLIST);
					int sel = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
					if (sel >= 0){
						CPlugin* plugin = CPluginManager::getInstance()->GetPlugin(sel);
						if (plugin != nullptr){
							::ShellExecute(nullptr, L"Open", plugin->m_sUrl.c_str(), nullptr, nullptr, SW_SHOW);
						}
					}
				}
				break;
			}
			break;
		case CBN_DROPDOWN:
			//switch( wID ){
			//default:
			//	break;
			//}
			break;	/* CBN_DROPDOWN */
		case EN_KILLFOCUS:
			//switch( wID ){
			//default:
			//	break;
			//}
			break;
		}

		break;	/* WM_COMMAND */
//@@@ 2001.02.04 Start by MIK: Popup Help
	case WM_HELP:
		{
			HELPINFO *p = (HELPINFO *)lParam;
			MyWinHelp( (HWND)p->hItemHandle, HELP_WM_HELP, (ULONG_PTR)(LPVOID)p_helpids );	// 2006.10.10 ryoji MyWinHelpに変更に変更
		}
		return TRUE;
		/*NOTREACHED*/
		//break;
//@@@ 2001.02.04 End

//@@@ 2001.12.22 Start by MIK: Context Menu Help
	//Context Menu
	case WM_CONTEXTMENU:
		MyWinHelp( hwndDlg, HELP_CONTEXTMENU, (ULONG_PTR)(LPVOID)p_helpids );	// 2006.10.10 ryoji MyWinHelpに変更に変更
		return TRUE;
//@@@ 2001.12.22 End
	}
	return FALSE;
}

/*!
	ダイアログ上のコントロールにデータを設定する

	@param hwndDlg ダイアログボックスのウィンドウハンドル
*/
void CPropPlugin::SetData( HWND hwndDlg )
{
	//プラグインを有効にする
	::CheckDlgButton( hwndDlg, IDC_CHECK_PluginEnable, m_Common.m_sPlugin.m_bEnablePlugin );

	//プラグインリスト
	SetData_LIST( hwndDlg );
	
	EnablePluginPropInput( hwndDlg );
	return;
}

/*!
	ダイアログ上のコントロールにデータを設定する

	@param hwndDlg ダイアログボックスのウィンドウハンドル
*/
void CPropPlugin::SetData_LIST( HWND hwndDlg )
{
	int index;
	LVITEM sItem;
	PluginRec* plugin_table = m_Common.m_sPlugin.m_PluginTable;

	::EnableWindow( ::GetDlgItem( hwndDlg, IDC_PLUGIN_Remove ), FALSE );
	::EnableWindow( ::GetDlgItem( hwndDlg, IDC_PLUGIN_OPTION ), FALSE );
	::EnableWindow( ::GetDlgItem( hwndDlg, IDC_PLUGIN_README ), FALSE );
	::EnableWindow( ::GetDlgItem( hwndDlg, IDC_PLUGIN_URL ), FALSE );

	//プラグインリスト
	HWND hListView = ::GetDlgItem( hwndDlg, IDC_PLUGINLIST );

	ListView_DeleteAllItems( hListView );

	for( index = 0; index < MAX_PLUGIN; ++index ){
		std::wstring sDirName;	//CPlugin.GetDirName()の結果保持変数
		CPlugin* plugin = CPluginManager::getInstance()->GetPlugin( index );

		//番号
		WCHAR buf[4];
		memset_raw( &sItem, 0, sizeof( sItem ));
		sItem.mask = LVIF_TEXT | LVIF_PARAM;
		sItem.iItem = index;
		sItem.iSubItem = 0;
		_itow( index, buf, 10 );
		sItem.pszText = buf;
		sItem.lParam = index;
		ListView_InsertItem( hListView, &sItem );

		//名前
		memset_raw( &sItem, 0, sizeof( sItem ));
		sItem.iItem = index;
		sItem.mask = LVIF_TEXT;
		sItem.iSubItem = 1;
		if( plugin ){
			sItem.pszText = const_cast<LPWSTR>( plugin->m_sName.c_str() );
		}else{
			sItem.pszText = const_cast<WCHAR*>(L"-");
		}
		ListView_SetItem( hListView, &sItem );

		//状態
		memset_raw( &sItem, 0, sizeof( sItem ));
		sItem.iItem = index;
		sItem.mask = LVIF_TEXT;
		sItem.iSubItem = 2;
		switch( plugin_table[index].m_state ){
		case PLS_INSTALLED: sItem.pszText = const_cast<WCHAR*>(LS(STR_PROPCOMPLG_STATE1)); break;
		case PLS_UPDATED:   sItem.pszText = const_cast<WCHAR*>(LS(STR_PROPCOMPLG_STATE2)); break;
		case PLS_STOPPED:   sItem.pszText = const_cast<WCHAR*>(LS(STR_PROPCOMPLG_STATE3)); break;
		case PLS_LOADED:    sItem.pszText = const_cast<WCHAR*>(LS(STR_PROPCOMPLG_STATE4)); break;
		case PLS_DELETED:   sItem.pszText = const_cast<WCHAR*>(LS(STR_PROPCOMPLG_STATE5)); break;
		case PLS_NONE:      sItem.pszText = const_cast<WCHAR*>(L""); break;
		default:            sItem.pszText = const_cast<WCHAR*>(LS(STR_PROPCOMPLG_STATE6)); break;
		}
		ListView_SetItem( hListView, &sItem );
		
		//読込
		sItem.iItem = index;
		sItem.mask = LVIF_TEXT;
		sItem.iSubItem = 3;
		if( plugin_table[index].m_state != PLS_NONE ){
			sItem.pszText = const_cast<WCHAR*>(plugin ? LS(STR_PROPCOMPLG_LOAD) : L"");
		}else{
			sItem.pszText = const_cast<WCHAR*>(L"");
		}
		ListView_SetItem( hListView, &sItem );

		//フォルダー
		memset_raw( &sItem, 0, sizeof( sItem ));
		sItem.iItem = index;
		sItem.mask = LVIF_TEXT;
		sItem.iSubItem = 4;
		switch( plugin_table[index].m_state ){
		case PLS_INSTALLED:
		case PLS_UPDATED:
		case PLS_STOPPED:
		case PLS_LOADED:
			if( plugin ){
				sDirName = plugin->GetFolderName();
				sItem.pszText = const_cast<LPWSTR>( sDirName.c_str() );
			}else{
				sItem.pszText = const_cast<LPWSTR>( plugin_table[index].m_szName );
			}
			break;
		default:
			sItem.pszText = const_cast<WCHAR*>(L"");
		}
		ListView_SetItem( hListView, &sItem );
	}
	
	//	リストビューの行選択を可能にする．
	//	IE 3.x以降が入っている場合のみ動作する．
	//	これが無くても，番号部分しか選択できないだけで操作自体は可能．
	DWORD dwStyle;
	dwStyle = ListView_GetExtendedListViewStyle( hListView );
	dwStyle |= LVS_EX_FULLROWSELECT;
	ListView_SetExtendedListViewStyle( hListView, dwStyle );

	return;
}

/*!
	ダイアログ上のコントロールからデータを取得してメモリに格納する

	@param hwndDlg ダイアログボックスのウィンドウハンドル
*/
int CPropPlugin::GetData( HWND hwndDlg )
{
	//プラグインを有効にする
	m_Common.m_sPlugin.m_bEnablePlugin = ::IsDlgButtonChecked( hwndDlg, IDC_CHECK_PluginEnable );

	//プラグインリストは今のところ変更できる部分がない
	//「新規プラグイン追加」はm_Commonに直接書き込むので、この関数ですることはない

	return TRUE;
}

struct ColumnData_CPropPlugin_Init {
	int titleId;
	int width;
};

/*!
	ダイアログ上のコントロールを初期化する

	@param hwndDlg ダイアログボックスのウィンドウハンドル
*/
void CPropPlugin::InitDialog( HWND hwndDlg )
{
	const struct ColumnData_CPropPlugin_Init ColumnList[] = {
		{ STR_PROPCOMPLG_LIST1, 40 },
		{ STR_PROPCOMPLG_LIST2, 200 },
		{ STR_PROPCOMPLG_LIST3, 40 },
		{ STR_PROPCOMPLG_LIST4, 40 },
		{ STR_PROPCOMPLG_LIST5, 150 },
	};

	//	ListViewの初期化
	HWND hListView = ::GetDlgItem( hwndDlg, IDC_PLUGINLIST );

	LVCOLUMN sColumn;
	int pos;
	RECT rc;
	::GetWindowRect( hListView, &rc );
	int width = rc.right - rc.left;
	
	for( pos = 0; pos < _countof( ColumnList ); ++pos ){
		
		memset_raw( &sColumn, 0, sizeof( sColumn ));
		sColumn.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_FMT;
		sColumn.pszText = const_cast<WCHAR*>(LS(ColumnList[pos].titleId));
		sColumn.cx = ColumnList[pos].width * width / 499;
		sColumn.iSubItem = pos;
		sColumn.fmt = LVCFMT_LEFT;
		
		if( ListView_InsertColumn( hListView, pos, &sColumn ) < 0 ){
			PleaseReportToAuthor( hwndDlg, L"PropComMacro::InitDlg::ColumnRegistrationFail" );
			return;	//	よくわからんけど失敗した
		}
	}
}

/*! 「プラグイン」シート上のアイテムの有効・無効を適切に設定する

	@date 2009.12.06 syat 新規作成
	@date 2010.08.21 Moca プラグイン無効状態でも削除操作などを可能にする
*/
void CPropPlugin::EnablePluginPropInput(HWND hwndDlg)
{
	if( !::IsDlgButtonChecked( hwndDlg, IDC_CHECK_PluginEnable ) )
	{
		::EnableWindow( ::GetDlgItem( hwndDlg, IDC_PLUGIN_SearchNew         ), FALSE );
		::EnableWindow( ::GetDlgItem( hwndDlg, IDC_PLUGIN_INST_ZIP          ), FALSE );
	}
	else
	{
		::EnableWindow( ::GetDlgItem( hwndDlg, IDC_PLUGIN_SearchNew         ), TRUE );
		CZipFile	cZipFile;
		::EnableWindow( ::GetDlgItem( hwndDlg, IDC_PLUGIN_INST_ZIP          ), cZipFile.IsOk() );
	}
}

//	Readme ファイルの取得	2011/11/2 Uchi
std::wstring CPropPlugin::GetReadMeFile(const std::wstring& sName)
{
	std::wstring sReadMeName = CPluginManager::getInstance()->GetBaseDir()
		+ sName + L"\\ReadMe.txt";
	CFile* fl = new CFile(sReadMeName.c_str());
	if (!fl->IsFileExist()) {
		sReadMeName = CPluginManager::getInstance()->GetBaseDir()
			+ sName + L"\\" + sName + L".txt";
		delete fl;
		fl = new CFile(sReadMeName.c_str());
	}
	if (!fl->IsFileExist()) {
		// exeフォルダー配下
		sReadMeName = CPluginManager::getInstance()->GetExePluginDir()
			+ sName + L"\\ReadMe.txt";
		delete fl;
		fl = new CFile(sReadMeName.c_str());
		if (!fl->IsFileExist()) {
			sReadMeName = CPluginManager::getInstance()->GetExePluginDir()
				+ sName + L"\\" + sName + L".txt";
			delete fl;
			fl = new CFile(sReadMeName.c_str());
		}
	}

	if (!fl->IsFileExist()) {
		sReadMeName.clear();
	}
	delete fl;
	return sReadMeName;
}

/*!
	Readme ファイルの表示

	@date 2011/11/2 Uchi

	@return true: 成功, false: 失敗
*/
bool CPropPlugin::BrowseReadMe(const std::wstring& sReadMeName)
{
	// -- -- -- -- コマンドライン文字列を生成 -- -- -- -- //
	CCommandLineString cCmdLineBuf;

	//アプリケーションパス
	WCHAR szExePath[MAX_PATH + 1];
	::GetModuleFileName( nullptr, szExePath, _countof( szExePath ) );
	cCmdLineBuf.AppendF( L"\"%s\"", szExePath );

	// ファイル名
	cCmdLineBuf.AppendF( L" \"%s\"", sReadMeName.c_str() );

	// コマンドラインオプション
	cCmdLineBuf.AppendF(L" -R -CODE=99");

	// グループID
	int nGroup = GetDllShareData().m_sNodes.m_nGroupSequences;
	if( nGroup > 0 ){
		cCmdLineBuf.AppendF( L" -GROUP=%d", nGroup+1 );
	}

	//CreateProcessに渡すSTARTUPINFOを作成
	STARTUPINFO	sui;
	::GetStartupInfo(&sui);

	PROCESS_INFORMATION	pi;
	ZeroMemory( &pi, sizeof(pi) );

	WCHAR	szCmdLine[1024];
	wcscpy_s(szCmdLine, _countof(szCmdLine), cCmdLineBuf.c_str());
	//リソースリーク対策
	BOOL bRet = ::CreateProcess( nullptr, szCmdLine, nullptr, nullptr, TRUE,
		CREATE_NEW_CONSOLE, nullptr, nullptr, &sui, &pi );

	//プロセス作成に成功した場合
	if ( bRet )
	{
		//スレッドハンドルは使わないので閉じておく
		::CloseHandle( pi.hThread );
		//プロセスハンドルは使わないので閉じておく
		::CloseHandle( pi.hProcess );
	}

	return ( bRet != FALSE );
}

static void LoadPluginTemp(CommonSetting& common, CMenuDrawer& cMenuDrawer)
{
	{
		// 2013.05.31 コントロールプロセスなら即時読み込み
		CPluginManager::getInstance()->LoadAllPlugin( &common );
		// ツールバーアイコンの更新
		const CPlug::Array& plugs = CJackManager::getInstance()->GetPlugs( PP_COMMAND );
		cMenuDrawer.m_pcIcons->ResetExtend();
		for( CPlug::ArrayIter it = plugs.cbegin(); it != plugs.cend(); it++ ) {
			int iBitmap = CMenuDrawer::TOOLBAR_ICON_PLUGCOMMAND_DEFAULT - 1;
			const CPlug* plug = *it;
			if( !plug->m_sIcon.empty() ){
				iBitmap = cMenuDrawer.m_pcIcons->Add( plug->m_cPlugin.GetFilePath( plug->m_sIcon ).c_str() );
			}
			cMenuDrawer.AddToolButton( iBitmap, plug->GetFunctionCode() );
		}
	}
}
